package com.flyqiu.common.spring;


import jakarta.servlet.http.HttpServletRequest;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;


public class FlyQiuSpringContextTools {
    private static AutowireCapableBeanFactory autowireCapableBeanFactory;

    /**
     * 上下文对象实例
     */
    private static ApplicationContext applicationContext;


    public static void setApplicationContext(ApplicationContext applicationContext, AutowireCapableBeanFactory factory) throws BeansException {
        FlyQiuSpringContextTools.applicationContext = applicationContext;
        FlyQiuSpringContextTools.autowireCapableBeanFactory = factory;
    }

    /**
     * 获取applicationContext
     *
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 获取当前上下文对象
     *
     * @return
     */
    public static String getWebContextPath() {
        Environment environment = getApplicationContext().getEnvironment();
        String contextPath = environment.getProperty("server.servlet.context-path");
        if (StringUtils.isAllBlank(contextPath)) {
            contextPath = "/";
        }
        return contextPath;
    }

    /**
     * 获取当前上下文对象
     *
     * @return
     */
    public static Integer getServerPort() {
        Environment environment = getApplicationContext().getEnvironment();
        return environment.getProperty("server.port", Integer.class);
    }

    /**
     * 获取HttpServletRequest
     */
    public static HttpServletRequest getHttpServletRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }

    /**
     * 获取域名
     *
     * @return
     */
    public static String getDomainName() {
        HttpServletRequest httpServletRequest = getHttpServletRequest();
        return httpServletRequest.getServerName();
    }

    public static String getDomain() {
        HttpServletRequest request = getHttpServletRequest();
        StringBuffer url = request.getRequestURL();
        return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
    }

    public static String getOrigin() {
        HttpServletRequest request = getHttpServletRequest();
        return request.getHeader("Origin");
    }

    /**
     * 通过name获取 Bean.
     *
     * @param name
     * @return
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /**
     * 通过class获取Bean.
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    public static String[] getAllBeans() {
        return getApplicationContext().getBeanDefinitionNames();
    }

    /**
     * 通过name,以及Clazz返回指定的Bean
     *
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }


    public static <T> Map<String, T> getBeans(Class<T> clazz) {
        return getApplicationContext().getBeansOfType(clazz);
    }

    /**
     * 获取指定类型的bean
     *
     * @param clazz
     * @param throwEx
     * @param <T>
     * @return
     */
    public static <T> Map<String, T> getBeans(Class<T> clazz, boolean throwEx) {
        try {
            return getBeans(clazz);
        } catch (Exception e) {
            if (!throwEx) {
                e.printStackTrace();
                return null;
            }
            throw e;
        }

    }

    @SneakyThrows
    public static <T> T newInstanceAndAutowire(Class<T> clazz) {
        T instance = clazz.newInstance();
        autowireCapableBeanFactory.autowireBean(instance);
        return instance;
    }

    /**
     * 自动注入对象
     *
     * @param object
     * @param <T>
     * @return
     */
    public static <T> T autowire(T object) {
        autowireCapableBeanFactory.autowireBean(object);
        return object;
    }

    /**
     * 获取请求头全部参数
     *
     * @param request
     * @return
     */
    public static Map<String, String> getHeaders(HttpServletRequest request) {
        Map<String, String> headerMap = new HashMap<>();
        Enumeration<String> enumeration = request.getHeaderNames();
        while (enumeration.hasMoreElements()) {
            String name = enumeration.nextElement();
            String value = request.getHeader(name);
            headerMap.put(name, value);
        }
        return headerMap;
    }
}
